"""


    PAL liveControl

    liveControl.LiveControl is the base class of all PAL control surfaces
    It inherits _Framework.ControlSurface.ControlSurface and add
    some basic stuffs:
        Log stderr and stdout (see pal_config to tune paths)
        Extend show_message to handle args like print
        Print incoming sysex messages
        
    also overrides receive_midi to fix _Framework code.
    
"""

# site import
import os.path

# Live imports
try:
    import Live
    from _Framework.ControlSurface import ControlSurface
    from _Framework.InputControlElement import MIDI_PB_TYPE
except:
    import LiveMock as Live
    from PAL._FrameworkMock.ControlSurface import ControlSurface
    from PAL._FrameworkMock.InputControlElement import MIDI_PB_TYPE

# PAL imports
import tools
import pal_config
import UDP

class LiveControl(ControlSurface):
    def __init__( self, c_instance, name=None ):
        ControlSurface.__init__( self, c_instance )
        if name is None:
            name= "PAL_"+__name__
        self.name = name.replace(' ','_')
        self._outLog = None
        self._errLog = None
        
        self.start_logging()
        self.show_message( name, 'initialized.', 'Log='+self._outLog.fileName )

        self.server = UDP.Server()
        self.server.open()

#    def _register_control(self, control):
#        print "REGISTERING CONTROL", control
#        ControlSurface._register_control(self, control )

#    def _register_component(self, component):
#        print "REGISTERING COMPONENT", component
#        ControlSurface._register_component(self, component )

    def start_logging(self):
        """
        Activate the logs. reimp to use other log system.
        """
        self._outLog = tools.Log(
            os.path.join(pal_config.LOGPATH,self.name+"_OUT.txt"), out=True
        )
        self._errLog = tools.Log(
            os.path.join(pal_config.LOGPATH,self.name+"_ERR.txt"), err=True
        )

    def stop_logging(self):
        """
        Restore default outputs and stop logging.
        You need to reimp this if you reimplemented start_logging
        """
        if self._outLog is not None:
            self._outLog.restore_sys()
        if self._errLog is not None:
            self._errLog.restore_sys()

    def _str_or_repr(self, o):
        if isinstance(o,(str,unicode)):
            return o
        return repr(o)

    def show_message( self, *args ):
        """
        Show message to the live user.
        Overrided to allow the same input as print.
        """
        msg = ' '.join([self._str_or_repr(i) for i in args])
        ControlSurface.show_message( self, msg )
        print "Message in Live:", msg

    def disconnect(self):
        """
        Live -> Script: Called right before we get disconnected from Live.
        Overrided to call self.stop_logging()
        """
        ControlSurface.disconnect( self )
        self.stop_logging()
        
#it looks like this is not needed anymore:
#    def is_extension(self):
#        '''Must return True if this class is an extension control'''
#        return False

    def receive_midi(self, midi_bytes):
        """
        Live -> Script
        MIDI messages are only received through this function, when explicitly 
        forwarded in 'build_midi_map'.
        
        Overrided to debug the fault assess to self._forwarding_registry
        """
        assert (midi_bytes != None)
        assert isinstance(midi_bytes, tuple)
        self.set_suppress_rebuild_requests(True)
        if (len(midi_bytes) is 3):
            msg_type = (midi_bytes[0] & 240)
            forwarding_key = [midi_bytes[0]]
            if (msg_type is not MIDI_PB_TYPE):
                forwarding_key.append(midi_bytes[1])
            recipient = self._forwarding_registry.get(tuple(forwarding_key))
            if (recipient != None):
                recipient.receive_value(midi_bytes[2])
        else:
            self.handle_sysex(midi_bytes)
        self.set_suppress_rebuild_requests(False)

    def handle_sysex(self, midi_bytes):
        """
        Overrided to print the sysex.
        """
        print "Got SysEx:", midi_bytes

    def update_display(self):
        ControlSurface.update_display(self)
        self.ServerReceive()
        
    def ServerReceive(self):
        d = self.server.recv()
        if d:
            print "PAL SERVER GOT DATA:", d, repr(d)
